package com.yanqu.road.logic.rank;

import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.pb.rank.RankProto;
import com.yanqu.road.pb.union.cross.CrossUnionProto;
import com.yanqu.road.utils.date.DateHelper;
import org.apache.mina.util.ConcurrentHashSet;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class UnionRankMsgModel {
    private int groupId;
    private int rankNum = GameConfig.UNION_RANK_DEFAULT_MAX_COUNT;
    private int activityId;
    private long updateTime;
    private long crossReqTime;
    private long activityEndTime;
    private RankProto.UnionRankListMsg.Builder rankListMsg = RankProto.UnionRankListMsg.newBuilder();

    /**
     * 缓存的成员名单,为了支持不同组的商会在一起 k:unionUid k:userId v:serverId
     */
    private Map<String, Map<Long, CrossUnionProto.UnionMemberTemp>> memberIdsMap = new ConcurrentHashMap<>();
    /**
     * 活动跨服请求锁定排行标志
     */
    private boolean isNeedSendToActivityCross;

    /**
     * 等待同步排行消息的玩家
     */
    private Set<Long> synUserId = new ConcurrentHashSet<>();

    public UnionRankMsgModel(int groupId, int activityId, long activityEndTime) {
        this.groupId = groupId;
        this.activityId = activityId;
        this.activityEndTime = activityEndTime;
    }

    public int getGroupId() {
        return groupId;
    }

    public int getRankNum() {
        return rankNum;
    }

    public void setRankNum(int rankNum) {
        this.rankNum = rankNum;
    }

    public long getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(long updateTime) {
        this.updateTime = updateTime;
    }

    public RankProto.UnionRankListMsg getRankListMsg() {
        return rankListMsg.build();
    }

    public void setRankListMsg(RankProto.UnionRankListMsg.Builder rankListMsg) {
        this.rankListMsg = rankListMsg;
    }

    public boolean isInReq() {
        long nowTime = DateHelper.getCurrentTime();
        if (nowTime - crossReqTime < 5 * 1000) { // 5秒内的请求只触发一次
            return true;
        }
        crossReqTime = nowTime;

        return false;
    }

    public boolean isNeedUpdate() {
        long nowTime = DateHelper.getCurrentTime();

        if (rankListMsg == null || rankListMsg.getRankListCount() == 0) {
            return true;
        }

        if (nowTime - updateTime > GameConfig.ABILITY_UNION_RANK_UPDATE_PER_TIME * 1000) {
            return true;
        }

        return false;
    }

    public boolean isNeedSendToActivityCross() {
        return isNeedSendToActivityCross;
    }

    public void setNeedSendToActivityCross(boolean needSendToActivityCross) {
        isNeedSendToActivityCross = needSendToActivityCross;
    }

    public void updateMemberIds(String unionId, List<CrossUnionProto.UnionMemberTemp> memberIds) {
        Map<Long, CrossUnionProto.UnionMemberTemp> memberServerMap = new HashMap<>();
        for (CrossUnionProto.UnionMemberTemp memberTemp : memberIds) {
            memberServerMap.put(memberTemp.getUserId(), memberTemp);
        }
        memberIdsMap.put(unionId, memberServerMap);
    }

    public Map<Long, CrossUnionProto.UnionMemberTemp> getMemberServerMap(String unionId) {
        return memberIdsMap.getOrDefault(unionId, new HashMap<>());
    }

    public void addSynPlayer(long userId) {
        synchronized (synUserId) {
            synUserId.add(userId);
        }
    }

    public List<Long> getSynUserIds() {
        List<Long> list = new ArrayList<>();
        synchronized (synUserId) {
            list.addAll(synUserId);
            synUserId.clear();
        }
        return list;
    }

    public RankProto.GetActivityUnionRankListRespMsg.Builder getClientRankListMsg(String unionUid) {
        RankProto.GetActivityUnionRankListRespMsg.Builder respMsg = RankProto.GetActivityUnionRankListRespMsg.newBuilder();
        respMsg.setActivityId(activityId);
        respMsg.setMyValue("0");
        respMsg.setMyRank(0);
        int myRank = 0;
        int rank = 0;
        for (RankProto.UnionRankTempMsg rankTempMsg : rankListMsg.getRankListList()) {
            rank++;
            if (Objects.equals(rankTempMsg.getUnionUid(), unionUid)) {
                respMsg.setMyValue(rankTempMsg.getValue());
                myRank = rank;
                break;
            }
        }
        respMsg.setMyRank(myRank);

        respMsg.setRank(rankListMsg);
        return respMsg;
    }

    public void setActivityEndTime(long activityEndTime) {
        this.activityEndTime = activityEndTime;
    }

    public long getActivityEndTime() {
        return activityEndTime;
    }

    public int getActivityId() {
        return activityId;
    }
}
